package com.caocaog.market.util;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import org.jeecg.common.exception.JeecgBootException;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Description 一些常用的集合工具类
 * @Author Van.Planifolia
 * @Date 2023/7/6
 * @Version 1.0
 */
public class CollectionsUtil {
    private static final Random random = new Random();

    /**
     * 从Collection中取出一个随机元素
     *
     * @param collection 被操作的集合
     * @param <T>        泛型
     * @return 随机搜寻结果
     */
    public static <T> T pickRandomElement(Collection<T> collection) {
        Objects.requireNonNull(collection, "集合不得为空！");

        int collectionSize = collection.size();
        if (collectionSize == 0) {
            throw new IllegalArgumentException("Collection must not be empty");
        }

        int randomIndex = random.nextInt(collectionSize);

        return collection.stream()
                .skip(randomIndex)
                .findFirst()
                .orElseThrow(() -> new JeecgBootException("无法搜寻到元素！")); // This line should never be reached
    }

    /**
     * 判断集合是否为空
     *
     * @param collection 要进行非空判断的集合信息
     * @return 判断的结果
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * 将map中的的值转化成List
     *
     * @param map 要被处理的元数据
     * @return 转化成的List
     */
    public static List<?> mapToList(@NotNull Map<?, ?> map) {
        return MapUtil.isEmpty(map) ? ListUtil.empty() : new ArrayList<>(map.values());
    }

    /**
     * 将原对象转化成需要转化成的集合信息 比如 Object o -> List 《Safer》
     * 线程安全
     *
     * @param obj   原对象的values()
     * @param clazz 目标对象的class类型
     * @param <T>   要转化的泛型类型
     * @return 转化完毕的List对象
     */
    public static <T> List<T> castList(@NotNull Object obj, @NotNull Class<T> clazz) {
        List<T> result = new CopyOnWriteArrayList<>();
        if (obj instanceof Collection<?>) {
            for (Object o : (Collection<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return Collections.emptyList();
    }

    /**
     * 将Redis中获取到的{@code Map<?,List<?>>} 里的所有List拆分出来并且返回数据
     *
     * @param redisMap 缓存中的ListMap
     * @return 拆分出来的全部ValuesList
     */
    public static <T> List<T> separateRedisMap(@NotNull Map<?, ?> redisMap, @Nullable Class<T> clazz) {
        List<T> resultList = new ArrayList<>();
        redisMap.forEach((k, v) -> {
            List<T> tList = castList(v, clazz);
            resultList.addAll(tList);
        });
        return resultList;
    }

    /**
     * 将请求中的ParameterMap转化成传统的MAP
     *
     * @param request 请求
     * @return 传统MAP结果
     */
    public static Map<String, String> requestParameterMapConverter(HttpServletRequest request) {
        TreeMap<String, String> map = new TreeMap<>();
        Map<String, String[]> reqMap = request.getParameterMap();
        for (String key : reqMap.keySet()) {
            String value = (reqMap.get(key))[0];
            map.put(key, value);
        }
        return map;
    }
}
